package com.googlecode.cswish.test;

import java.lang.reflect.Method;

import org.apache.commons.lang.StringUtils;
import org.junit.runner.JUnitCore;
import org.junit.runner.Request;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

/**
 * Run the JUnit method from the command line: className#methodName
 * 
 */
public class JavaClassRunner {

	public static void main(String... args) throws ClassNotFoundException {
		int extCode = 0;
		
		JavaClassRunner runner = new JavaClassRunner();
		
		for (String arg : args) {
			String[] classAndMethod = arg.split("#");
			String className = classAndMethod[0];
			String methodName = classAndMethod[1];
			
			boolean success = true;
			if (className.endsWith("Test")) {
				success = runner.runJUnit(className, methodName);
			} else {
				int index = methodName.indexOf('(');
				String argumentInfo = methodName.substring(index + 1, methodName.length() - 1);		// skip the last ')'
				String[] arguments = StringUtils.split(argumentInfo, ',');
				success = runner.runMethod(className, methodName, arguments);
			}
			if (success) {
				extCode = 1;
			}
		}
		
		System.exit(extCode);
	}
	
	private boolean runMethod(String className, String methodName, String[] arguments) {
		try {
			System.out.println("Run " + className + '#' + methodName + ", argurments is " + arguments);
			
			Class clazz = Class.forName(className);
			Method[] methods = clazz.getMethods();
			Method matchedMethod = null;
			for (Method method : methods) {
				if (method.getName().equals(methodName)) {
					matchedMethod = method;
					break;
				}
			}
			
			Object[] args = arguments;
			matchedMethod.invoke(clazz.newInstance(), args);
			return true;
		} catch (Exception ex) {
			ex.printStackTrace();
			return false;
		}
	}

	private boolean runJUnit(String className, String methodName) throws ClassNotFoundException {
		Request request = Request.method(Class.forName(className),
				methodName);
		
		Result result = new JUnitCore().run(request);
		
		System.out.println("Run " + className + '#' + methodName + ", Result=" + result.wasSuccessful());
		for (Failure failure : result.getFailures()) {
			failure.getException().printStackTrace();
		}
		
		return result.wasSuccessful();
	}
}